<template>
    <div ref="shape" class="shape" @contextmenu.prevent="contextmenu" @mousedown="handleDragendShape"
        :class="{ active: isActive }" style="width:100px;height:100px;">
        <span>

        </span>
        <!-- 旋转 -->
        <div class="rotation" @mousedown="handleRotate">
            <svg t="1680409561887" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
                p-id="2859" width="30" height="30">
                <path
                    d="M716.8 290.133333c-110.933333-102.4-281.6-106.666667-396.8-12.8S170.666667 537.6 247.466667 665.6c59.733333 106.666667 179.2 166.4 302.933333 149.333333s221.866667-102.4 256-221.866666c8.533333-34.133333 42.666667-51.2 76.8-42.666667 34.133333 8.533333 51.2 42.666667 42.666667 76.8-68.266667 226.133333-302.933333 354.133333-524.8 290.133333C174.933333 853.333333 42.666667 618.666667 106.666667 392.533333c42.666667-145.066667 153.6-256 298.666666-298.666666s298.666667 0 405.333334 102.4l81.066666-81.066667c8.533333-8.533333 21.333333-12.8 34.133334-8.533333 4.266667 12.8 12.8 21.333333 12.8 34.133333v264.533333c0 17.066667-12.8 29.866667-29.866667 29.866667h-260.266667c-12.8 0-25.6-8.533333-29.866666-17.066667s0-25.6 8.533333-34.133333l89.6-93.866667zM512 601.6c-46.933333 0-85.333333-38.4-85.333333-89.6s38.4-89.6 85.333333-89.6 85.333333 38.4 85.333333 89.6-38.4 89.6-85.333333 89.6z"
                    p-id="2860"></path>
            </svg>
        </div>
        <!-- 控制点 -->
        <div class="shape-point" :class="[item.direction, rotateClassName]"
            @mousedown="handleStretchedShape(item.direction, $event)" :style="{ top: item.top, left: item.left }"
            v-for="(item, index) in pointRenderData" :key="index"></div>
        <!-- 组件 -->
        <slot name="default"></slot>
    </div>
</template>
<script setup>
import { ref, reactive, computed } from 'vue'
import { throttleFrame } from '../../../utils/utils'
import { stretchedComponents } from '../../../utils/component'
import { userCardStore } from '../../../store/userCardStore'


const emit = defineEmits(["selectCom", "rightClick"]);
const cardStore = userCardStore()
const shape = ref(null)
const contextmenu = (e) => {
    console.log('右键菜单')
    emit('rightClick', e)
}
// 控制点
const pointRenderData = reactive([
    {
        top: '0%',
        left: '0%',
        direction: 'lt'
    },
    {
        top: '0%',
        left: '50%',
        direction: 't'
    },
    {
        top: '0%',
        left: '100%',
        direction: 'rt'
    },
    {
        top: '50%',
        left: '100%',
        direction: 'r'
    },
    {
        top: '100%',
        left: '100%',
        direction: 'rb'
    },
    {
        top: '100%',
        left: '50%',
        direction: 'b'
    },
    {
        top: '100%',
        left: '0%',
        direction: 'lb'
    },
    {
        top: '50%',
        left: '0%',
        direction: 'l'
    }
])
const props = defineProps({
    active: {
        type: Boolean
    },
    defaultStyle: {
        type: Object
    },
    scale: {
        type: Number
    }
})

const isActive = computed(() => {
    return props.active
})
const rotateClassName = computed(() => {
    const prefix = 'rotate-'
    const rotate = props.defaultStyle.rotate
    if (rotate > -22.5 && rotate <= 22.5) return prefix + 0
    else if (rotate > 22.5 && rotate <= 67.5) return prefix + 45
    else if (rotate > 67.5 && rotate <= 112.5) return prefix + 90
    else if (rotate > 112.5 && rotate <= 157.5) return prefix + 135
    else if (rotate > 157.5 || rotate <= -157.5) return prefix + 0
    else if (rotate > -157.5 && rotate <= -112.5) return prefix + 45
    else if (rotate > -112.5 && rotate <= -67.5) return prefix + 90
    else if (rotate > -67.5 && rotate <= -22.5) return prefix + 135
    return prefix + 0
})
/**
     * 拖动组件
     */
const handleDragendShape = (e) => {
    emit('selectCom')
    e.preventDefault()

    e.stopPropagation()

    let { top, left } = props.defaultStyle
    const startY = e.clientY
    const startX = e.clientX
    // 如果直接修改属性，值的类型会变为字符串，所以要转为数值型
    const startTop = parseFloat(top)
    const startLeft = parseFloat(left)
    const scale = props.scale || 1
    // 如果元素没有移动，则不保存快照
    const move = throttleFrame((moveEvent) => {
        const curX = moveEvent.clientX
        const curY = moveEvent.clientY
        top = (curY - startY) / scale + startTop
        left = (curX - startX) / scale + startLeft
        // // 修改当前组件样式
        cardStore.setCurStyle({ top, left })
    })
    const up = () => {
        document.removeEventListener('mousemove', move)
        document.removeEventListener('mouseup', up)
    }
    document.addEventListener('mousemove', move)
    document.addEventListener('mouseup', up)
}
/**
     * 拉伸组件
     */
const handleStretchedShape = (point, e) => {
    // 选择
    e.stopPropagation()
    e.preventDefault()

    const position = {
        top: props.defaultStyle.top,
        left: props.defaultStyle.left,
        height: props.defaultStyle.height,
        width: props.defaultStyle.width,
        rotate: props.defaultStyle.rotate
    }
    // 获取画布位移信息
    const editorRectInfo = document.querySelector('#editor').getBoundingClientRect()
    const scale = props.scale || 1
    // 获取 point 与实际拖动基准点的差值 @justJokee
    const move = throttleFrame((moveEvent) => {
        // 第一次点击时也会触发 move，所以会有“刚点击组件但未移动，组件的大小却改变了”的情况发生
        // 因此第一次点击时不触发 move 事件
        const curPositon = {
            x: (moveEvent.clientX - editorRectInfo.left) / scale,
            y: (moveEvent.clientY - editorRectInfo.top) / scale
        }
        const { top, left, width, height } = stretchedComponents(point, position, curPositon)
        cardStore.setCurStyle({ top, left, width, height })
    })

    const up = () => {
        document.removeEventListener('mousemove', move)
        document.removeEventListener('mouseup', up)
    }

    document.addEventListener('mousemove', move)
    document.addEventListener('mouseup', up)
}
/**
     * 旋转组件
     */
const handleRotate = (e) => {
    if (!shape.value) {
        return
    }
    e.preventDefault()
    e.stopPropagation()

    // 初始坐标和初始角度
    let { rotate } = { ...props.defaultStyle }
    const startY = e.clientY
    const startX = e.clientX
    const startRotate = rotate

    // 获取元素中心点位置
    const rect = shape.value.getBoundingClientRect()
    const centerX = rect.left + rect.width / 2
    const centerY = rect.top + rect.height / 2

    // 旋转前的角度
    const rotateDegreeBefore = Math.atan2(startY - centerY, startX - centerX) / (Math.PI / 180)

    // 如果元素没有移动，则不保存快照
    // let hasMove = false
    const move = throttleFrame((moveEvent) => {
        // hasMove = true
        const curX = moveEvent.clientX
        const curY = moveEvent.clientY
        // 旋转后的角度
        const rotateDegreeAfter = Math.atan2(curY - centerY, curX - centerX) / (Math.PI / 180)
        // 获取旋转的角度值
        rotate = startRotate + rotateDegreeAfter - rotateDegreeBefore
        // 修改当前组件样式
        cardStore.setCurStyle({ rotate })
    })

    const up = () => {
        document.removeEventListener('mousemove', move)
        document.removeEventListener('mouseup', up)
    }

    document.addEventListener('mousemove', move)
    document.addEventListener('mouseup', up)
}
</script>
  
<style scoped lang="less">
@import url(./shape.module.less);
</style>
  